package com.lin.generate.service.impl;


import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Maps;
import com.lin.generate.common.base.PageReqVO;
import com.lin.generate.common.enums.SystemConst;
import com.lin.generate.common.utill.*;
import com.lin.generate.common.vo.request.UserReqVO;
import com.lin.generate.common.vo.response.UserRespVO;
import com.lin.generate.entity.User;
import com.lin.generate.mapper.UserMapper;
import com.lin.generate.service.IUserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 用户表 服务实现类
 *
 * @author zhaolin
 * @date 2023-06-04
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    @Autowired
    private RedisUtil redisUtils;

    @Override
    public Boolean update(UserReqVO vo) {
        log.info("# 开始修改用户表,请求信息:{}", JsonUtils.toJson(vo));
        User entity = this.getById(vo.getId());
        if (Objects.nonNull(entity)) {
            BeanUtils.copyProperties(vo, entity);
            this.updateById(entity);
            log.info("# 结束修改用户表。");
            return true;
        }
        log.info("# 修改用户表失败。");
        return false;
    }

    @Override
    public IPage<UserRespVO> pageList(PageReqVO pageReqVO, UserReqVO vo) {
        log.info("# 开始分页查询用户表信息。");
        if (pageReqVO.getIsAll() == 1L) {
            pageReqVO.setPageNum(0L);
            pageReqVO.setPageSize(Long.MAX_VALUE);
        }
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(User::getCreateTime);
        if (Objects.nonNull(vo)) {

        }
        Page<User> page = new Page<>(pageReqVO.getPageNum(), pageReqVO.getPageSize());
        IPage<User> entityIPage = this.page(page, wrapper);
        IPage<UserRespVO> resultIPage = new Page<>();
        List<UserRespVO> resultRecord = ObjectConversion.copy(entityIPage.getRecords(), UserRespVO.class);
        resultIPage.setRecords(resultRecord);
        resultIPage.setTotal(entityIPage.getTotal());
        log.info("# 结束分页查询用户表信息。");
        return resultIPage;
    }

    @Override
    public UserRespVO getObjectById(Long id) {
        UserRespVO result = new UserRespVO();
        User entity = this.getById(id);
        if (Objects.nonNull(entity)) {
            BeanUtils.copyProperties(entity, result);
        }
        return result;
    }

    @Override
    public UserRespVO register(UserReqVO vo) {
        log.info("# 开始注册用户,请求信息:{}", JsonUtils.toJson(vo));
        //TODO 校验验证码
        // 用户名校验
        Long count = lambdaQuery().eq(User::getAccount, vo.getAccount()).count();
        //TODO 密码暂时不加密
        Asserts.check(count < 1L, "用户账户已存在。");
        //保存用户信息
        User entity = BeanUtil.copyProperties(vo, User.class);
        BeanUtils.copyProperties(vo, entity);
        this.save(entity);
        UserRespVO rs = BeanUtil.copyProperties(entity, UserRespVO.class);
        log.info("# 结束注册用户。");
        return rs;
    }

    @Override
    public UserRespVO login(UserReqVO vo) {
        log.info("# 用户登录,请求信息:{}", JsonUtils.toJson(vo));
        User user = lambdaQuery().eq(User::getAccount, vo.getAccount()).one();
        Asserts.notNull(user, "该用户不存在。");
        Asserts.check(Objects.equals(user.getPassword(), vo.getPassword()), "用户密码不正确，请重新输入。");
        UserRespVO rs = BeanUtil.copyProperties(user, UserRespVO.class);
        creatToken(rs);
        log.info("# 用户登录,响应信息:{}", JsonUtils.toJson(vo));
        return rs;
    }

    /**
     * 生成token
     * @param user
     */
    private void creatToken(UserRespVO user){
        Map<String, Object> map = Maps.newHashMap();
        map.put(SystemConst.TOKEN_USER_INFO.getMsg(), JSONObject.toJSONString(user));
        // token过期时间为一天
        String token = JwtHelper.createJWT(map, Long.valueOf(60 * 60 * 1000 * 24 * 7));
        redisUtils.set(token, user, SystemConst.SMALLPRO_LOGIN_VALID_TIME.getCode());
        user.setToken(token);
    }
}
